package com.meshnetics.gb.stack.mac.primitives;

import com.meshnetics.gb.stack.core.event.StackEventType;
import com.meshnetics.gb.stack.core.event.StackRequest;
import com.meshnetics.gb.stack.mac.RadioMACStackLayer;
import com.meshnetics.gb.stack.mac.type.ChannelMask;
import com.meshnetics.gb.stack.mac.type.ScanType;
import com.meshnetics.gb.type.impl.ByteUtils;
import com.meshnetics.gb.type.impl.zcl.TypeUInt;
import com.meshnetics.gb.type.impl.zcl.UInt;

import java.nio.ByteBuffer;

/**
 * WRITE DESCRIPTION HERE
 *
 * @author AKovylin
 */
public class MACScanRequest extends StackRequest implements MACCommand, MACReplyAwaited {
    public static final byte CODE = 0x58;

    private final ScanType scanType;
    private final ChannelMask scanChannels;
    private final UInt scanDuration;

    public MACScanRequest(ScanType scanType, ChannelMask scanChannels, int scanDuration) {
        this(scanType, scanChannels, (byte) (scanDuration & 0xff));
    }

    public MACScanRequest(ScanType scanType, ChannelMask scanChannels, byte scanDuration) {
        this(scanType, scanChannels, new Byte(scanDuration));
    }

    public MACScanRequest(ScanType scanType, ChannelMask scanChannels, Byte scanDuration) {
        this(scanType, scanChannels, (UInt) TypeUInt.UINT_8.fromObject(scanDuration));
    }

    public MACScanRequest(ScanType scanType, ChannelMask scanChannels, UInt scanDuration) {
        super("macScanRequest", StackEventType.LME_TYPE);
        if (scanType == null) {
            throw new NullPointerException("scanType is null");
        }
        if (scanChannels == null) {
            throw new NullPointerException("scanChannels is null");
        }
        if (scanDuration == null) {
            throw new NullPointerException("scanDuration is null");
        }
        int check = ((Number) scanDuration.toObject()).intValue();
        if (check < 0 || check > 14) {
            throw new IllegalArgumentException("invalid scanDuration, must be in range 0-14");
        }
        this.scanType = scanType;
        this.scanChannels = scanChannels;
        this.scanDuration = scanDuration.convert(TypeUInt.UINT_8);
    }

    public ScanType getScanType() {
        return scanType;
    }

    public ChannelMask getScanChannels() {
        return scanChannels;
    }

    public UInt getScanDurationType() {
        return scanDuration;
    }

    public Byte getScanDuration() {
        return (Byte) scanDuration.toObject();
    }

    public byte getCode() {
        return CODE;
    }

    public int getSize(RadioMACStackLayer layer) {
        return 6;
    }

    public void serialize(ByteBuffer bb, RadioMACStackLayer layer) {
        ByteUtils.ensureNotNull(bb);
        scanType.serialize(bb);
        scanChannels.serialize(bb);
        scanDuration.serialize(bb);
    }

    public String toString() {
        return getName() + '(' + scanType + ',' + scanChannels + ',' + scanDuration + ')';
    }
}
